package com.concurrent.data.thread.config;

/**
 * @author 哲思小辉
 * @version 1.0.0
 * @ClassName RabbitMQCofig.java
 * @Description RabbitMQ配置
 * @Param
 * @createTime 2020年06月19日 16:48:00
 */

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@Slf4j
public class RabbitMqConfig {

    public static final String RABBITMQ_QUEUE_NAME = "queueDemo";
    public static final String RABBITMQ_ORDER_QUEUE_NAME = "OrderQueueDemo";
    @Autowired
    private CachingConnectionFactory cachingConnectionFactory;

    @Bean
    public Queue commonQueue() {
        return new Queue(RabbitMqConfig.RABBITMQ_QUEUE_NAME);
    }

    @Bean
    public Queue orderQueue() {
        return new Queue(RabbitMqConfig.RABBITMQ_ORDER_QUEUE_NAME);
    }

    @Bean
    public DirectExchange directExchange() {
        return new DirectExchange("directExchange");
    }

    @Bean
    public TopicExchange topicExchange() {
        return new TopicExchange("topicExchange");
    }

    @Bean
    public FanoutExchange fanoutExchange() {
        return new FanoutExchange("fanoutExchange");
    }

    // 建立Queue与Exchange的绑定关系
    @Bean
    public Binding bindingExchangeMessage(Queue orderQueue, DirectExchange directExchange) {
        return BindingBuilder.bind(orderQueue).to(directExchange).with(
                RabbitMqConfig.RABBITMQ_ORDER_QUEUE_NAME);
    }

    @Bean
    public RabbitTemplate rabbitTemplate() {
        cachingConnectionFactory.setPublisherReturns(true);
        RabbitTemplate rabbitTemplate = new RabbitTemplate(cachingConnectionFactory);
        rabbitTemplate.setMandatory(true);

        rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
            if (ack) {
                log.info("消息发送成功: correlationData:({}),ack:({ack}),cause:({})", correlationData,
                        ack, cause);
            } else {
                log.info("消息发送失败: correlationData:({}),ack:({ack}),cause:({})", correlationData,
                        ack, cause);
            }
        });

        rabbitTemplate.setReturnCallback(
                (message, replyCode, replyText, exchange, routingKey) -> log.info(
                        "消息丢失:exchange({}),route({}),replyCode({}),replyText({}),message:{}", exchange,
                        routingKey, replyCode, replyText, message));

        return rabbitTemplate;
    }
}
